/* 
  License : GPLv3
  Author  : William Wong
  E-mail  : hzwhuang@gmail.com
  Language: C
*/
#include <gtk/gtk.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
static gint num = 0;
struct coursedata
{
	gfloat grades;
	gfloat credits;
	gfloat gp;
}data;
static gfloat gpac = 0;
static gfloat sumgp = 0;
static gfloat sumcredits = 0;
static GtkWidget *statusbar = NULL;
static GtkWidget *entry = NULL;
static GtkWidget *entry2 = NULL;
static GtkWidget *entry3 = NULL;
static GtkWidget *entry4 = NULL;
static gint context_id;
static gint cobo1;
static gint cobo2;
GdkPixbuf *create_pixbuf(const gchar * filename)
{
   GdkPixbuf *pixbuf;
   GError *error = NULL;
   pixbuf = gdk_pixbuf_new_from_file(filename, &error);
   if(!pixbuf) {
      fprintf(stderr, "%s\n", error->message);
      g_error_free(error);
   }
   return pixbuf;
}
static void calc()
{
	if(data.grades>=96)	data.gp=4.8;
	else if(data.grades>=93)	data.gp=4.5;
	else if(data.grades>=90)	data.gp=4.0;
	else if(data.grades>=86)	data.gp=3.8;
	else if(data.grades>=83)	data.gp=3.5;
	else if(data.grades>=80)	data.gp=3.0;
	else if(data.grades>=76)	data.gp=2.8;
	else if(data.grades>=73)	data.gp=2.5;
	else if(data.grades>=70)	data.gp=2.0;
	else if(data.grades>=66)	data.gp=1.8;
	else if(data.grades>=63)	data.gp=1.5;
	else if(data.grades>=60)	data.gp=1.0;
}

void xzentry(GtkEditable *entry, gchar *new_text, gint new_text_length, gint *position, gpointer gdata)
{
	const char *text = gtk_entry_get_text (GTK_ENTRY(entry));
	if( !strcmp(new_text, "0") ||
        !strcmp(new_text, "1") ||
        !strcmp(new_text, "2") ||
        !strcmp(new_text, "3") ||
        !strcmp(new_text, "4") ||
        !strcmp(new_text, "5") ||
        !strcmp(new_text, "6") ||
        !strcmp(new_text, "7") ||
        !strcmp(new_text, "8") ||
        !strcmp(new_text, "9") ||
        !strcmp(new_text, ".")
	)	return;
	else
	{
		gchar *result = g_utf8_strup (new_text, new_text_length);
        g_signal_handlers_block_by_func (entry,
                 (gpointer) xzentry, gdata);
        gtk_entry_set_text (GTK_ENTRY(entry), text);
        g_signal_handlers_unblock_by_func (entry,
                                   (gpointer) xzentry, gdata);
        g_signal_stop_emission_by_name (entry, "insert_text");
        g_free (result);
	}
}

void next(GtkWidget *widget, gpointer context_id)
{
	gchar *mess;
	gfloat temp = atof(gtk_entry_get_text (GTK_ENTRY(entry2)));
	data.credits = temp;
	temp = atof(gtk_entry_get_text (GTK_ENTRY(entry)));
	data.grades = temp;
	calc();
	if(data.credits!=0)
	{
		sumgp += data.gp*data.credits;
		sumcredits += data.credits;
		mess = g_strdup_printf("%i course(s) inputted.", ++num);
		gtk_combo_box_set_active (GTK_COMBO_BOX(entry3), -1);
		gtk_combo_box_set_active (GTK_COMBO_BOX(entry4), -1);
		gtk_entry_set_text(GTK_ENTRY(entry), "");
		gtk_entry_set_text(GTK_ENTRY(entry2), "");
	}
	else	mess = g_strdup_printf("Please input complete course data.");
	gtk_statusbar_push(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(context_id), mess);
	g_free(mess);
}

void combo_selected(GtkWidget *widget, gpointer gdata)
{
	cobo1 = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
	g_signal_handlers_block_by_func(G_OBJECT(entry), G_CALLBACK(xzentry), NULL);
	if(cobo1 >= 0)
	switch(cobo1){
		case 0: gtk_entry_set_text(GTK_ENTRY(entry), "95");break;
		case 1: gtk_entry_set_text(GTK_ENTRY(entry), "85");break;
		case 2: gtk_entry_set_text(GTK_ENTRY(entry), "75");break;
		case 3: gtk_entry_set_text(GTK_ENTRY(entry), "65");break;
		default: gtk_entry_set_text(GTK_ENTRY(entry), "0");break;
	}
	g_signal_handlers_unblock_by_func(G_OBJECT(entry), G_CALLBACK(xzentry), NULL);
}

void cobo2_selected(GtkWidget *widget, gpointer gdata)
{
	cobo2 = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
	if(cobo2 >= 0)
	switch(cobo2){
		case 0: gtk_entry_set_text(GTK_ENTRY(entry2), "2");break;
		case 1: gtk_entry_set_text(GTK_ENTRY(entry2), "3");break;
		case 2: gtk_entry_set_text(GTK_ENTRY(entry2), "4");break;
		case 3: gtk_entry_set_text(GTK_ENTRY(entry2), "5");break;
		case 4: gtk_entry_set_text(GTK_ENTRY(entry2), "3");break;
		case 5: gtk_entry_set_text(GTK_ENTRY(entry2), "3");break;
		case 6: gtk_entry_set_text(GTK_ENTRY(entry2), "2");break;
		case 7: gtk_entry_set_text(GTK_ENTRY(entry2), "1");break;
		case 8: gtk_entry_set_text(GTK_ENTRY(entry2), "2");break;
		case 9: gtk_entry_set_text(GTK_ENTRY(entry2), "3");break;
		case 10: gtk_entry_set_text(GTK_ENTRY(entry2), "1");break;
		case 11: gtk_entry_set_text(GTK_ENTRY(entry2), "2.5");break;
		default:break;
	}
}

void finish(GtkWidget *widget, gpointer window)
{
	GtkWidget *dialog = NULL;
	gchar mess[25];
	gchar buffer[50];
	if(sumcredits != 0)
	{
		gpac = sumgp/sumcredits;
		strcpy(mess, "你的平均绩点是");
		dialog = gtk_message_dialog_new(window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO,
			GTK_BUTTONS_OK, "%s %2.2f !", mess, gpac);
		gtk_window_set_title(GTK_WINDOW(dialog), "计算结果");
		gtk_dialog_run(GTK_DIALOG(dialog));
		gtk_widget_destroy(dialog);
	}
	else
	{
		gchar *mess;
		mess = g_strdup_printf("Hey,man! You didn't input any data.");
		gtk_statusbar_push(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(context_id), mess);
		g_free(mess);
	}
}

void clearall (GtkWidget *widget, gpointer gdata)
{
	sumcredits = 0;
	sumgp = 0;
	gpac = 0;
	num = 0;
	gchar *mess;
	gtk_entry_set_text(GTK_ENTRY(entry), "");
	gtk_entry_set_text(GTK_ENTRY(entry2), "");
	gtk_combo_box_set_active (GTK_COMBO_BOX(entry3), -1);
	gtk_combo_box_set_active (GTK_COMBO_BOX(entry4), -1);
	mess = g_strdup_printf("Database is empty now.");
	gtk_statusbar_push(GTK_STATUSBAR(statusbar), GPOINTER_TO_INT(context_id), mess);
	g_free(mess);
}

void show_about(GtkWidget *widget, gpointer data)
{
	GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file("img/icon.png", NULL);
	GtkWidget *dialog = gtk_about_dialog_new();
	gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
	gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog), "GPAC-gtk");
	gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), "1.1"); 
	gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), 
		"(c) William Wong");
	gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), 
		"一个简单的GPA计算小程序");
	gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), pixbuf);
	gtk_window_set_icon(GTK_WINDOW(dialog), create_pixbuf("img/icon.png"));
	g_object_unref(pixbuf), pixbuf = NULL;
	gtk_dialog_run(GTK_DIALOG (dialog));
	gtk_widget_destroy(dialog);
}

gboolean show_quit(GtkWidget *window, GdkEvent *event, gpointer data)
{
	GtkWidget *dialog;
	GtkWidget *label;
	dialog = gtk_dialog_new_with_buttons("确认退出", GTK_WINDOW(window),
	GTK_DIALOG_MODAL,GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,GTK_STOCK_OK,GTK_RESPONSE_OK,NULL);
	label = gtk_label_new ("你确定要退出平均绩点计算器么？");
	gtk_box_pack_start(GTK_BOX (GTK_DIALOG (dialog) -> vbox), label, FALSE, TRUE, 25);
	gtk_widget_show_all(dialog);
	gint choose;
	choose = gtk_dialog_run(GTK_DIALOG(dialog));
	if(choose == GTK_RESPONSE_OK)	gtk_main_quit();
	else if(choose == GTK_RESPONSE_REJECT)	gtk_widget_destroy(dialog);
	return TRUE;
}

int main(int argc, char *argv[])
{
	GtkWidget *button = NULL;
	GtkWidget *window = NULL;
	GtkWidget *label = NULL;
	GtkWidget *vbox = NULL;
	GtkWidget *hbox2 = NULL;
	GtkWidget *hbox = NULL;

	gtk_init (&argc, &argv);
	
	data.grades = 0;
	data.credits = 0;
	data.gp = 0;
	//Main window
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_container_set_border_width (GTK_CONTAINER (window), 10);
	gtk_window_set_title (GTK_WINDOW (window), "平均绩点计算器");
	gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
	gtk_widget_realize (window);
	gtk_widget_set_size_request(window, 230,150);
	gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
	gtk_window_set_icon(GTK_WINDOW(window), create_pixbuf("img/icon.png"));
	g_signal_connect(G_OBJECT(window), "delete-event",
		G_CALLBACK(show_quit), NULL);
	//Container
	vbox = gtk_vbox_new (FALSE, 6);
	gtk_container_add (GTK_CONTAINER (window), vbox);
	hbox2 = gtk_hbox_new (FALSE, 4);
	hbox = gtk_hbox_new (FALSE, 4);
	gtk_box_pack_start(GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
	entry = gtk_entry_new ();
	entry2 = gtk_entry_new ();
	gtk_entry_set_max_length(GTK_ENTRY (entry), 3);
	gtk_entry_set_max_length(GTK_ENTRY (entry2), 3);
	label = gtk_label_new("成绩：");
	gtk_box_pack_start(GTK_BOX (hbox), label, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX (hbox), entry, TRUE, TRUE, 0);
	entry3 = gtk_combo_box_new_text();
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry3), "优秀");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry3), "良好");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry3), "中等");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry3), "通过");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry3), "不及格");
	g_signal_connect(G_OBJECT(entry3), "changed",
		G_CALLBACK(combo_selected), NULL);
	gtk_box_pack_start(GTK_BOX (hbox), entry3, FALSE, FALSE, 0);
	g_signal_connect(G_OBJECT(entry), "insert-text",
		G_CALLBACK(xzentry), NULL);
	label = gtk_label_new("学分：");
	gtk_box_pack_start(GTK_BOX (hbox2), label, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX (hbox2), entry2, TRUE, TRUE, 0);
	g_signal_connect(G_OBJECT(entry2), "insert-text",
		G_CALLBACK(xzentry), NULL);
	entry4 = gtk_combo_box_new_text();
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "C++");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "大学英语");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "大学物理");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "高等数学");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "画法几何");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "几何与代数");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "近代史纲要");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "军事理论");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "军训");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "思想道德修养");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "体育");
	gtk_combo_box_append_text(GTK_COMBO_BOX(entry4), "无机化学");
	g_signal_connect(G_OBJECT(entry4), "changed",
		G_CALLBACK(cobo2_selected), NULL);
	gtk_box_pack_start(GTK_BOX (hbox2), entry4, FALSE, FALSE, 0);
	hbox = gtk_hbox_new (TRUE, 4);
	gtk_box_pack_start(GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
	button = gtk_button_new_with_label("关于");
	g_signal_connect(G_OBJECT(button), "clicked",
		G_CALLBACK(show_about), NULL);
	gtk_box_pack_start(GTK_BOX (hbox), button, TRUE, TRUE, 0);
	button = gtk_button_new_with_label("清空");
	g_signal_connect(G_OBJECT(button), "clicked",
		G_CALLBACK(clearall), NULL);
	gtk_box_pack_start(GTK_BOX (hbox), button, TRUE, TRUE, 0);
	button = gtk_button_new_with_label("添加");
	statusbar = gtk_statusbar_new();
	gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(statusbar), FALSE);
	context_id = gtk_statusbar_get_context_id(GTK_STATUSBAR (statusbar), "statusbar");
	gtk_statusbar_push (GTK_STATUSBAR (statusbar), GPOINTER_TO_INT(context_id), "Plese input data.");
	g_signal_connect(G_OBJECT(button), "clicked",
		G_CALLBACK(next), GINT_TO_POINTER(context_id));
	gtk_box_pack_start(GTK_BOX (hbox), button, TRUE, TRUE, 0);
	
	button = gtk_button_new_with_label("计算");
	g_signal_connect(G_OBJECT(button), "clicked",
		G_CALLBACK(finish), window);
	gtk_box_pack_start(GTK_BOX (hbox), button, TRUE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX (vbox), statusbar, FALSE, FALSE, 0);
	
	//Main loop
	gtk_widget_show_all (window);
	gtk_main();
	return 0;
}